#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "book.h"
#include "myfile.h"
#include "general.h"




union union_node {
	BOOK union_book;
	STUDENT union_student;
	RECORD union_record;
};
typedef union union_node UNODE;

struct node {
    UNODE node_data;
    struct node *next;
};
typedef struct node NODE;


NODE * modify_book(NODE *head);
void write_back_book(NODE *head);
int get_length_of_list(NODE *head);
void print_list(NODE *head);
NODE * pre_read_book();
NODE * create_list(int n);
NODE * delete_book(NODE *head, char *book_name, char *book_id);
NODE * search_book(NODE *head, char *book_name, char *book_id, int *out);
void delete_node(NODE *p, NODE *q);
NODE * tail_insert(NODE *head);
NODE * head_insert(NODE *head);
NODE * create_node();
void insert_student();
void show_student(char *name, int lines);



NODE * create_node() {
	NODE *temp;
	temp = (NODE *)malloc(sizeof(NODE));
	return temp;
}

NODE * head_insert(NODE *head) {
	NODE *p;
	p = create_node();
	if (head == NULL) {
		head = p;
		head->next = NULL;
	} else {
		p->next = head;
		head = p;
	}
	return head;
}

NODE * tail_insert(NODE *head) {
	NODE *p, *q;
	p = create_node();
	if (head == NULL) {
		head = q = p;
	} else {
		for(q = head; q->next != NULL; q = q->next);
		q->next = p;
		q = p;
	}
	q->next = NULL;
	return head;
}

void delete_node(NODE *p, NODE *q) {
	p->next = q->next;
	free(q);
	q = NULL;
}

NODE * create_list(int n) {
	NODE *head = NULL; 
	int i;
	for (i = 0; i < n; i++) {
		//head = head_insert(head);
		head = tail_insert(head);
	}
	return head;
}

void print_book_list(NODE *head) {
	NODE *p = head;
	while (p != NULL) {
		printf("%s\t%s\t%s\t%d\t%4.2f\t%s\t%s\t%d\t%d\n", 
				p->node_data.union_book.book_name,
				p->node_data.union_book.book_id,
				p->node_data.union_book.book_author,
				p->node_data.union_book.book_publish_date,
				p->node_data.union_book.book_price,
				p->node_data.union_book.book_press,
				p->node_data.union_book.book_category,
				p->node_data.union_book.book_original_stock,
				p->node_data.union_book.book_lent
			  );
		p = p->next;
	}
}
void print_student_list(NODE *head) {
	NODE *p = head;
	while (p != NULL) {
		printf("%s\t%s\n", 
				p->node_data.union_student.student_name,
				p->node_data.union_student.student_id
			  );
		p = p->next;
	}
}




int get_length_of_list(NODE *head) {
	int ret = 0;
	NODE *p;
	p = head;
	while (p != NULL) {
		ret++;
		p = p->next;
	}
	return ret;
}


NODE * pre_read_book() {
	int i, n;
	BOOK book;
	BOOK *point_to_book;
	point_to_book = &book;

	NODE *head, *p;
	head = NULL;

	FILE *fp;

	n = lines_of_file("book");
	head = p = create_list(n);

	if ((fp = fopen("book", "rb")) == NULL) {
		printf("open file failed in function pre_read_book");
		exit(1);
	}

	for (i = 0; i < n; i++) {
		rewind(fp);
		fseek(fp, i * sizeof(BOOK), 0);
		fread(point_to_book, sizeof(BOOK), 1, fp);
		strcpy(p->node_data.union_book.book_name, point_to_book->book_name);
		strcpy(p->node_data.union_book.book_id,	point_to_book->book_id);
		strcpy(p->node_data.union_book.book_author,	point_to_book->book_author);
		p->node_data.union_book.book_publish_date =	point_to_book->book_publish_date;
		p->node_data.union_book.book_price =	point_to_book->book_price;
		strcpy(p->node_data.union_book.book_press, point_to_book->book_press);
		strcpy(p->node_data.union_book.book_category, point_to_book->book_category);
		p->node_data.union_book.book_original_stock =	point_to_book->book_original_stock;
		p->node_data.union_book.book_lent =	point_to_book->book_lent;

		p = p->next;
	}
	fclose(fp);
	return head;
}

NODE * search_book(NODE *head, char *book_name, char *book_id, int *out) {
	NODE *p;
	for (p = head; p != NULL; p = p->next) {
		if (!strcmp(p->node_data.union_book.book_name, book_name) && !strcmp(p->node_data.union_book.book_id, book_id)) {
			*out = p->node_data.union_book.book_lent;
			break;
		}
	}
	if (p == NULL) {
		return NULL;
	} else {
		return p;
	}
}

NODE * delete_book(NODE *head, char *book_name, char *book_id) {
	NODE *p, *q;
	for (q = p = head; p != NULL; q = p, p = p->next) {
		if (!strcmp(p->node_data.union_book.book_name, book_name) && !strcmp(p->node_data.union_book.book_id, book_id) ) {
			if (p->node_data.union_book.book_lent == 0) {
				delete_node(q, p);
				break;
			} else {
				printf("someone has borrowed this book: %s\t%s\t it cannot be delete\n", book_name, book_id);
				break;
			}
		}
	}
	return head;
}

void write_back_book(NODE *head) {
	FILE *fp;
	if ((fp = fopen("bookbak", "wb+")) == NULL) {
		printf("open file failed\n");
		exit(1);
	}

	NODE *p; 
	BOOK *q;
	p = head;
	
	rewind(fp);
	fseek(fp, 0, 2);
	while (p != NULL) {
		q = &p->node_data.union_book;
		fwrite(q, sizeof(BOOK), 1, fp);
		p = p->next;
	}
	fclose(fp);
}

NODE * modify_book(NODE *head) {
	NODE *p, *q;
	char name[10];
	char id[10];
	char author[10];
	int publish_date;
	float price;
	char press[10];
	char category[10];
	int original_stock;
	int lent;
	int choice = 1;
	int flag = 1;

	printf("please input the name and id\n");
	scanf("%s %s", name, id);
	while (flag) {
		p = search_book(head, name, id, &choice);
		if (p == NULL) {
			printf("<%s %s> does not exist\n", name, id);
			printf("please input the name and id you want to modify again\n");
			scanf("%s %s", name, id);
		} 
		if (p != NULL && choice) {
			printf("someone has borrowed the book:<%s\t%s>\nit cannot be modified\n", name, id);
			printf("\nplease input the name and id you want to modify again\n");
			scanf("%s %s", name, id);
		} 
		if (p != NULL && !choice) {
			do {
				printf("please choose a member to modify\n");
				printf("\n1-book_name\t2-book_id\t3-book_author\t4-book_publish_date\t5-book_price\t6-book_press\t7-book_category\t8-book_original_stock\t9-book_lent\t0-exit\n");
				scanf("%d", &choice);
				switch (choice) {
					case 1:
						q = head;
						do {
							printf("please input the new book_name\n");
							scanf("%s", name);
							for (q = head; q != NULL; q = q->next) {
								if (!strcmp(q->node_data.union_book.book_name, name)) {
									printf("name has exist\n");
									break;
								}
							}
						} while (q != NULL);

						if (q == NULL) {
							strcpy(p->node_data.union_book.book_name, name);
						}
						break;


					case 2:
						printf("please input the new book_id\n");
						scanf("%s", id);
						strcpy(p->node_data.union_book.book_id, id);
						break;
					case 3:
						printf("please input the new book_author\n");
						scanf("%s", author);
						strcpy(p->node_data.union_book.book_author, author);
						break;
					case 4:
						printf("please input the new book_publish_date\n");
						scanf("%d", &publish_date);
						p->node_data.union_book.book_publish_date = publish_date;
						break;
					case 5:
						printf("please input the new book_price\n");
						scanf("%f", &price);
						p->node_data.union_book.book_price = price;
						break;
					case 6:
						printf("please input the new book_press\n");
						scanf("%s", press);
						strcpy(p->node_data.union_book.book_press, press);
						break;
					case 7:
						printf("please input the new book_category\n");
						scanf("%s", category);
						strcpy(p->node_data.union_book.book_category, category);
						break;
					case 8:
						printf("please input the new book_original_stock\n");
						scanf("%d", &original_stock);
						p->node_data.union_book.book_original_stock= original_stock;
						break;
					case 9:
						printf("please input the new book_lent\n");
						scanf("%d", &lent);
						p->node_data.union_book.book_lent= lent;
						break;
					case 0:
						break;
						/* 
					default :
						printf("your input is incorrect\nfuck your eyes\n");
						break;
 */
				}
			}while (choice);
			flag = 0;
		}
	}
	return head;
}


//void borrow_book(NODE *head_of_book_list, NODE *head_of_student_list, NODE *head_of_record_list) {
void borrow_book(NODE *head_of_book_list) {
	char book_name[10];
	char book_id[10];
	int flag = 1;
	int output;



	NODE *book_list, *student_list, *record_list, *p, *q, *r;
	book_list = head_of_book_list;
	//student_list = head_of_student_list;
	//record_list = head_of_record_list;




	printf("please input the book_name\n");
	scanf("%s", book_name);
	printf("please input the book_id\n");
	scanf("%s", book_id);

	while (flag) {

		p = search_book(book_list, book_name, book_id, &output);
		if (p == NULL) {
			printf("the book: <%s %s> does not exist\n", book_name, book_id);
			printf("please input the book_name\n");
			scanf("%s", book_name);
			printf("please input the book_id\n");
			scanf("%s", book_id);

		} 
		if (p != NULL && p->node_data.union_book.book_original_stock == output) {
			printf("all of the books have been borrowed\n");
			printf("please input the book_name\n");
			scanf("%s", book_name);
			printf("please input the book_id\n");
			scanf("%s", book_id);
		}
		if (p != NULL && p->node_data.union_book.book_original_stock > output) {
			printf("please input your student id\n");
			break;
		}

	}

}

void insert_student() {
	STUDENT student, tmp_student; 
	STUDENT *point_to_student, *point_to_tmp_student;
	point_to_student = &student;
	point_to_tmp_student = &tmp_student;
	int i;
	int lines;

	lines = lines_of_file("student");

	FILE *fp;
	if ((fp = fopen("student", "ab+")) == NULL) {
		printf("open file failed in function insert_student\n");
		exit(1);
	}
	do {
		printf("请输入学生名(最多十个字符)：");
		scanf("%s", point_to_tmp_student->student_name);
		printf("请输入学生编号(最多十个字符)：");
		scanf("%s", point_to_tmp_student->student_id);
		for (i = 0; i < lines; i++) {
			rewind(fp);
			fseek(fp, i * sizeof(STUDENT), 0);
			fread(point_to_student, sizeof(STUDENT), 1, fp);
			if (strcmp(point_to_tmp_student->student_name, point_to_student->student_name) == 0) {
				if(strcmp(point_to_tmp_student->student_id, point_to_student->student_id) == 0){
					printf("\n该编号已存在请重新输入\n\n");
					break;
				}
			}
		}
		if (i == lines) {
			break;
		}
	} while(1);
	point_to_tmp_student->endflag = '\n';
	printf("student name:%s\n", point_to_tmp_student->student_name);
	printf("student id:%s\n", point_to_tmp_student->student_id);
	printf("endflag<%c>endflag", point_to_tmp_student->endflag);

	fseek(fp, 0, 2);
	fwrite(point_to_tmp_student, sizeof(STUDENT), 1, fp);
	printf("\n录入成功！回到主菜单\n");
	fclose(fp);
}

void show_student(char *name, int lines) {
	int i;
	FILE *fp;
	STUDENT student;
	STUDENT *point_to_student;
	point_to_student = &student;

	if ((fp = fopen(name, "rb")) == NULL) {
		printf("open file failed in function show_student");
		exit(1);
	}

	printf("学生姓名\t学生编号\n");
	for (i = 0; i < lines; i++) {
		rewind(fp);
		fseek(fp, i * sizeof(STUDENT), 0);
		fread(point_to_student, sizeof(STUDENT), 1, fp);
		printf("%s\t%s\n", point_to_student->student_name, point_to_student->student_id);
	}
	printf("\n浏览学生完毕！回到主菜单\n");
	fclose(fp);
}

NODE * pre_read_student() {
	int i, n;
	STUDENT student;
	STUDENT *point_to_student;
	point_to_student = &student;

	NODE *head, *p;
	head = NULL;

	n = lines_of_file("student");
	head = p = create_list(n);

	FILE *fp;
	if ((fp = fopen("student", "rb")) == NULL) {
		printf("open file failed\n");
		exit(1);
	}

	for (i = 0; i < n; i++) {
		rewind(fp);
		fseek(fp, i * sizeof(STUDENT), 0);
		fread(point_to_student, sizeof(STUDENT), 1, fp);
		strcpy(p->node_data.union_student.student_name, point_to_student->student_name);
		strcpy(p->node_data.union_student.student_id, point_to_student->student_id);
		p = p->next;
	}
	fclose(fp);
	return head;
}

NODE * search_student(NODE *head, char *student_name, char *student_id) {
	NODE *p;
	for (p = head; p != NULL; p = p->next) {
		if (!strcmp(p->node_data.union_student.student_name, student_name) && !strcmp(p->node_data.union_student.student_id, student_id)) {
			break;
		}
	}
	if (p == NULL) {
		return NULL;
	} else {
		return p;
	}
}

void write_back_student(NODE *head) {
	FILE *fp;
	if ((fp = fopen("studentbak", "wb+")) == NULL) {
		printf("open file failed\n");
		exit(1);
	}

	NODE *p; 
	STUDENT *q;
	p = head;
	
	rewind(fp);
	fseek(fp, 0, 2);
	while (p != NULL) {
		q = &p->node_data.union_student;
		fwrite(q, sizeof(STUDENT), 1, fp);
		p = p->next;
	}
	fclose(fp);
}

NODE * modify_student(NODE *head) {
	NODE *p, *q;
	char name[10];
	char id[10];
	int choice = 1;

	printf("please input the student name and id\n");
	scanf("%s %s", name, id);
	while (1) {
		p = search_student(head, name, id);
		if (p == NULL) {
			printf("studetn <%s %s> does not exist\n", name, id);
			printf("please input the name and id you want to modify again\n");
			scanf("%s %s", name, id);
		} else {
			do {
				printf("please choose a member to modify\n");
				printf("\n1-student_name\t2-student_id\t0-exit\n");
				scanf("%d", &choice);
				switch (choice) {
					case 1:
						q = head;
						do {
							printf("please input the new student_name\n");
							scanf("%s", name);
							for (q = head; q != NULL; q = q->next) {
								if (!strcmp(q->node_data.union_book.book_name, name)) {
									printf("name has exist\n");
									break;
								}
							}
						} while (q != NULL);

						if (q == NULL) {
							strcpy(p->node_data.union_student.student_name, name);
						}
						break;

					case 2:
						printf("please input the new student_id\n");
						scanf("%s", id);
						strcpy(p->node_data.union_student.student_id, id);
						break;
	
					case 0:
						break;
						/* 
						   default :
						   printf("your input is incorrect\nfuck your eyes\n");
						   break;
						   */
				}
			}while (choice);
			break;
		}
	}

	print_student_list(head);
	return head;
}

void insert_record() {
	RECORD record, tmp_record; 
	RECORD *point_to_record, *point_to_tmp_record;
	point_to_record = &record;
	point_to_tmp_record = &tmp_record;
	int i;
	int lines;

	lines = lines_of_file("record");

	FILE *fp;
	if ((fp = fopen("record", "ab+")) == NULL) {
		printf("open file failed in function insert_student\n");
		exit(1);
	}
	do {
		printf("请输入学生编号：");
		scanf("%s", point_to_tmp_record->student_id);
		printf("请输入图书编号：");
		scanf("%s", point_to_tmp_record->book_id);
		for (i = 0; i < lines; i++) {
			rewind(fp);
			fseek(fp, i * sizeof(RECORD), 0);
			fread(point_to_record, sizeof(RECORD), 1, fp);
			if (strcmp(point_to_tmp_record->student_id, point_to_record->student_id) == 0) {
				if(strcmp(point_to_tmp_record->book_id, point_to_record->book_id) == 0){
					printf("\n该编号已存在请重新输入\n\n");
					break;
				}
			}
		}
		if (i == lines) {
			break;
		}
	} while(1);

	point_to_tmp_record->endflag = '\n';
	printf("student id:%s\n", point_to_tmp_record->student_id);
	printf("book id:%s\n", point_to_tmp_record->book_id);
	printf("endflag<%c>endflag", point_to_tmp_record->endflag);

	fseek(fp, 0, 2);
	fwrite(point_to_tmp_record, sizeof(RECORD), 1, fp);
	printf("\n录入成功！回到主菜单\n");
	fclose(fp);
}


void show_record(char *name, int lines) {
	int i;
	FILE *fp;
	RECORD record;
	RECORD *point_to_record;
	point_to_record = &record;

	if ((fp = fopen(name, "rb")) == NULL) {
		printf("open file failed in function show_record");
		exit(1);
	}

	printf("学生编号\t图书编号\n");
	for (i = 0; i < lines; i++) {
		rewind(fp);
		fseek(fp, i * sizeof(RECORD), 0);
		fread(point_to_record, sizeof(RECORD), 1, fp);
		printf("%s\t%s\n", point_to_record->student_id, point_to_record->book_id);
	}
	printf("\n浏览完毕！回到主菜单\n");
	fclose(fp);
}





void menu() {
	int i = 0;
	printf("\n\n");
	for(i=0;i<80;i++)
		printf("#");
	printf("\n\n");	
	printf("\t\t1-----图书录入\t\t\t");
	printf("2-----图书浏览\n\n");
	printf("\t\t3-----图书查询\t\t\t");
	printf("4-----修改删除图书\n\n");
	printf("\t\t5-----借阅图书\t\t\t");
	printf("6-----归还图书\n\n");
	printf("\t\t7-----借阅查询\t\t\t\n");
	printf("\n\t\t\t\t输入其他任意键退出\n");
	printf("\n\n");
	for(i=0;i<80;i++)
		printf("#");
	printf("\n\n");
}

int main(){
//	judge_if_exist("book", "borrow", "student");
//	menu();
	//insert_book();
//	printf("below show book\n");
//	show_book("book", lines_of_file("book"));
	
//	printf("below printlist\n");
	NODE *head = NULL;
//	head = pre_read_book();
//	printf("\nthe length of list is:\n%d\n", get_length_of_list(head));
//	print_list(head);

//	printf("\nafter delete\n");
//	print_list(delete_book(head, "name4", "id4"));

//	write_back_book(head);
//	printf("\nafter writeback\n");
//	show_book("bookbak", get_length_of_list(head));

//	modify_book(head);
//	print_list(head);
//	print_list(delete_book(head, "name5", "id5"));
//	printf("###################################\n");
//	modify_book(head);

//	borrow_book(head);
//	insert_student();
//	show_student("student", lines_of_file("student"));
//	head = pre_read_student();
//	print_student_list(head);
//	write_back_student(head);
//	show_student("studentbak", get_length_of_list(head));
//	modify_student(head);

	insert_record();
	show_record("record", lines_of_file("record"));
	printf("%d",lines_of_file("record"));
	return 0;
}
